﻿#define _CRT_SECURE_NO_WARNINGS

//// List.h
//
//namespace bit
//{
//	template<class T>
//	struct ListNode
//	{
//		ListNode<T>* _next;
//		ListNode<T>* _prev;
//		T _data;
//		ListNode(T&& data)
//			:_next(nullptr)
//			, _prev(nullptr)
//			, _data(move(data))
//		{}
//		template <class... Args>
//		ListNode(Args&&... args)
//			: _next(nullptr)
//			, _prev(nullptr)
//			, _data(std::forward<Args>(args)...)
//		{}
//	};
//
//	template<class T, class Ref, class Ptr>
//	struct ListIterator
//	{
//		typedef ListNode<T> Node;
//		typedef ListIterator<T, Ref, Ptr> Self;
//		Node* _node;
//		ListIterator(Node* node)
//			:_node(node)
//		{}
//
//		// ++it;
//		Self& operator++()
//		{
//			_node = _node->_next;
//			return *this;
//		}
//
//		Self& operator--()
//		{
//			_node = _node->_prev;
//			return *this;
//		}
//
//		Ref operator*()
//		{
//			return _node->_data;
//		}
//
//		bool operator!=(const Self& it)
//		{
//			return _node != it._node;
//		}
//	};
//
//	template<class T>
//	class list
//	{
//		typedef ListNode<T> Node;
//	public:
//		typedef ListIterator<T, T&, T*> iterator;
//		typedef ListIterator<T, const T&, const T*> const_iterator;
//
//		iterator begin()
//		{
//			return iterator(_head->_next);
//		}
//
//		iterator end()
//		{
//			return iterator(_head);
//		}
//
//		void empty_init()
//		{
//			_head = new Node();
//			_head->_next = _head;
//			_head->_prev = _head;
//		}
//
//		list()
//		{
//			empty_init();
//		}
//
//		void push_back(const T& x)
//		{
//			insert(end(), x);
//		}
//
//		void push_back(T&& x)
//		{
//			insert(end(), move(x));
//		}
//
//		iterator insert(iterator pos, const T& x)
//		{
//			Node* cur = pos._node;
//			Node* newnode = new Node(x);
//			Node* prev = cur->_prev;
//			// prev newnode cur
//
//			prev->_next = newnode;
//			newnode->_prev = prev;
//			newnode->_next = cur;
//			cur->_prev = newnode;
//			return iterator(newnode);
//		}
//
//		iterator insert(iterator pos, T&& x)
//		{
//			Node * cur = pos._node;
//			Node* newnode = new Node(move(x));
//			Node* prev = cur->_prev;
//
//			// prev newnode cur
//			prev->_next = newnode;
//			newnode->_prev = prev;
//			newnode->_next = cur;
//			cur->_prev = newnode;
//
//			return iterator(newnode);
//		}
//
//		template <class... Args>
//		void emplace_back(Args&&... args)
//		{
//			insert(end(), std::forward<Args>(args)...);
//		}
//
//		// 原理：本质编译器根据可变参数模板⽣成对应参数的函数 
//		/*void emplace_back(string& s)
//		{
//			insert(end(), std::forward<string>(s));
//		}
//
//		void emplace_back(string&& s)
//		{
//			insert(end(), std::forward<string>(s));
//		}
//
//		void emplace_back(const char* s)
//		{
//			insert(end(), std::forward<const char*>(s));
//		}
//		*/
//
//		template <class... Args>
//		iterator insert(iterator pos, Args&&... args)
//		{
//			Node* cur = pos._node;
//			Node* newnode = new Node(std::forward<Args>(args)...);
//			Node* prev = cur->_prev;
//
//			// prev newnode cur
//			prev->_next = newnode;
//			newnode->_prev = prev;
//			newnode->_next = cur;
//			cur->_prev = newnode;
//
//			return iterator(newnode);
//		}
//	private:
//		Node* _head;
//	};
//}



//class Person
//{
//public:
//	Person(const char* name = "", int age = 0)
//		:_name(name)
//		, _age(age)
//	{}
//	/*Person(const Person& p)
//		:_name(p._name)
//		,_age(p._age)
//	{}*/
//
//	/*Person& operator=(const Person& p)
//	{
//		if(this != &p)
//		{
//			_name = p._name;
//			_age = p._age;
//		}
//
//		return *this;
//	}*/
//
//	/*~Person()
//	{}*/
//
//private:
//	tcq::string _name;
//	int _age;
//};
//
//int main()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	Person s4;
//	s4 = std::move(s2);
//
//	return 0;
//}

//
//class Person
//{
//public:
//	Person(const char* name = "", int age = 0)
//		:_name(name)
//		, _age(age)
//	{}
//	Person(const Person& p)
//		:_name(p._name)
//		, _age(p._age)
//	{}
//	Person(Person&& p) = default;
//
//	//Person(const Person& p) = delete;
//
//private:
//	tcq::string _name;
//	int _age;
//};
//
//int main()
//{
//	Person s1;
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//	return 0;
//}


//#include<functional>
//
//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	Plus(int n = 10)
//		:_n(n)
//	{}
//
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return (a + b) * _n;
//	}
//
//private:
//		int _n;
//};
//
//int main()
//{
//	// 包装各种可调用对象 
//	function<int(int, int)> f1 = f;
//	function<int(int, int)> f2 = Functor();
//	function<int(int, int)> f3 = [](int a, int b) {return a + b; };
//
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	// 包装静态成员函数 
//	// 成员函数要指定类域并且前⾯加&才能获取地址 
//	function<int(int, int)> f4 = &Plus::plusi;
//	cout << f4(1, 1) << endl;
//
//	// 包装普通成员函数 
//	// 普通成员函数还有⼀个隐含的this指针参数，所以绑定时传对象或者对象的指针过去都可以 
//	function<double(Plus*, double, double)> f5 = &Plus::plusd;
//	Plus pd;
//	cout << f5(&pd, 1.1, 1.1) << endl;
//
//	function<double(Plus, double, double)> f6 = &Plus::plusd;
//	cout << f6(pd, 1.1, 1.1) << endl;
//	cout << f6(pd, 1.1, 1.1) << endl;
//
//	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//	cout << f7(move(pd), 1.1, 1.1) << endl;
//	cout << f7(Plus(), 1.1, 1.1) << endl;
//
//	return 0;
//}


#include<functional>

using placeholders::_1;
using placeholders::_2;
using placeholders::_3;

int Sub(int a, int b)
{
	return (a - b) * 10;
}

int SubX(int a, int b, int c)
{
	return (a - b - c) * 10;
}

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}
	double plusd(double a, double b)
	{
		return a + b;
	}
};

int main()
{
	auto sub1 = bind(Sub, _1, _2);
	cout << sub1(10, 5) << endl;

	// bind 本质返回的⼀个仿函数对象 
	// 调整参数顺序（不常⽤） 
	// _1代表第⼀个实参 
	// _2代表第⼆个实参 
	// ...
	auto sub2 = bind(Sub, _2, _1);
	cout << sub2(10, 5) << endl;

	// 调整参数个数 （常⽤） 
	auto sub3 = bind(Sub, 100, _1);
	cout << sub3(5) << endl;

	auto sub4 = bind(Sub, _1, 100);
	cout << sub4(5) << endl;

	// 分别绑死第123个参数 
	auto sub5 = bind(SubX, 100, _1, _2);
	cout << sub5(5, 1) << endl;

	auto sub6 = bind(SubX, _1, 100, _2);
	cout << sub6(5, 1) << endl;

	auto sub7 = bind(SubX, _1, _2, 100);
	cout << sub7(5, 1) << endl;

	// 成员函数对象进行绑死，就不需要每次都传递了 
	function<double(Plus&&, double, double)> f6 = &Plus::plusd;
	Plus pd;
	cout << f6(move(pd), 1.1, 1.1) << endl;
	cout << f6(Plus(), 1.1, 1.1) << endl;

	// bind⼀般用于，绑死⼀些固定参数 
	function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);
	cout << f7(1.1, 1.1) << endl;

	// 计算复利的lambda 
	auto func1 = [](double rate, double money, int year)->double 
		{
		double ret = money;
		for (int i = 0; i < year; i++)
		{
			ret += ret * rate;
		}
		return ret - money;
	};

	// 绑死⼀些参数，实现出⽀持不同年华利率，不同⾦额和不同年份计算出复利的结算利息 
	function<double(double)> func3_1_5 = bind(func1, 0.015, _1, 3);
	function<double(double)> func5_1_5 = bind(func1, 0.015, _1, 5);
	function<double(double)> func10_2_5 = bind(func1, 0.025, _1, 10);
	function<double(double)> func20_3_5 = bind(func1, 0.035, _1, 30);

	cout << func3_1_5(1000000) << endl;
	cout << func5_1_5(1000000) << endl;
	cout << func10_2_5(1000000) << endl;
	cout << func20_3_5(1000000) << endl;

	return 0;
}
